package com.qiangzi.workflow.engine.bpmn.base;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Element;
import org.springframework.util.Assert;

import com.qiangzi.workflow.engine.bpmn.flow.SequenceFlow;
import com.qiangzi.workflow.engine.core.MyEngine;

public abstract class Node extends BaseElement {

	private List<Edge> incoming = new ArrayList<Edge>();

	private List<Edge> outgoing = new ArrayList<Edge>();

	public List<Edge> getIncoming() {
		return incoming;
	}

	public List<Edge> getOutgoing() {
		return outgoing;
	}

	public void parse(Element element) throws Exception {
		super.parse(element);
	}

	protected void deploy() {
		super.deploy();
	}

	public void ignore(ProcessInstance instance) {

		setState(State.IGNORED, instance);
		LOGGER.debug("node [{}] -> ignored", this.getId());

		// 开始扭转边的状态,这些边应该都是NEW的状态
		List<Edge> edges = outgoing;

		if (null == edges) {
			return;
		}

		// 如果有出边,出边一律设置为IGNORED
		for (Edge edge : edges) {

			Assert.isTrue(State.NEW == edge.getState(), "wrong edge state of " + this.getId() + " " + edge.getId());
			edge.ignore(instance);

		}

	}

	/**
	 * 默认执行算法,特殊的需要覆盖
	 * 
	 * @throws Exception
	 */
	@Override
	public void invoke(ProcessInstance instance, MyEngine engine) throws Exception {

		setState(State.INVOKED, instance);
		LOGGER.debug("node [{}] -> invoked", getId());

		// 再处理各个边
		List<Edge> edges = this.getOutgoing();

		if (null == edges) {
			return;
		}

		for (Edge edge : edges) {

			if (edge instanceof SequenceFlow) {
				// 这个内部会设置边的状态是invoked还是ignored
				// 主要看表达式是否存在以及是否计算结果为true|false
				edge.invoke(instance, engine);
			} else {
				LOGGER.warn("unknown edge id is {}", edge.getId());
			}

		}

	}

}